#import <Foundation/Foundation.h>
#import "SFUEventCollection.h"
#import "SFUPersistentEventCollection.h"
#import "SFUEventSearchEngine.h"
#import "EventListViewer.h"
#import "EventSearchView.h"
#import "MapBuildingSearchDelegate.h"
#import "ParsingUtilities.h"

/**
 * An EventManager is an object representing the management
 * system for all event-oriented tasks.
 *
 * The event manager is the main interface into the event subsystem, and all
 * calls from outside modules should only need to communicate with this class.
 *
 * The event manager deallocates all dependent shared instances, and thus it 
 * is on the onus of the caller of this class to call the deallocate method
 * after there is no longer any need to interface with the event subsystem.
 *
 * Maintenance of both cached and persistent events is handled by the event
 * manager. The class also serves as the delegate of the event viewer 
 * (e.g. handling bookmark/unbookmark requests).
 *
 * The event manager can be used to do the following tasks:
 *      1) Search for events from SFU websites using keyword filters.
 *      2) Search for events from SFU websites using keyword filters and then
 *         filter only the events with a parsable location on campus.
 *      3) Display the information about a single event or a list of events.
 *      4) Display the bookmarked (persistent) events.
 *      5) Send a request to view the location of an event on a map.
 * 
 * @author      James Lin
 * @version     0.9.1
 * @since       0.7.0
 */
@interface EventManager : NSObject <EventViewerDelegate> {
	SFUPersistentEventCollection*    storedEvents;         // Events stored on disk
	SFUEventCollection*              cachedEvents;         // Events stored in memory
	id<SFUEventSearchEngineDelegate> searchEngineDelegate; // Delegate for search engine events
	id<MapBuildingSearchDelegate>    viewBuildingDelegate; // Delegate for viewing building
}

/**
 * Retrieve the shared instance of the event manager.
 *
 * @return  the shared instance of EventManager
 */
+ (EventManager*)sharedEventManager;

/**
 * Get the delegate handling search events.
 *
 * @return  the delegate handling search events
 * @see     SFUEventSearchEngineDelegate
 */
- (id<SFUEventSearchEngineDelegate>)searchDelegate;

/**
 * Set the delegate handling search events.
 *
 * @param delegate  the delegate handling search events
 * @see             SFUEventSearchEngineDelegate
 */
- (void)setSearchDelegate:(id<SFUEventSearchEngineDelegate>)delegate;

/**
 * Set the delegate handling view building events.
 *
 * @param delegate  the delegate handling view building events
 * @see             MapBuildingSearchDelegate
 */
- (void)setViewBuildingDelegate:(id<MapBuildingSearchDelegate>)delegate;

/**
 * Retrieve bookmarked events.
 *
 * @return  an array of all the bookmarked events
 */
- (NSArray*)getBookmarkedEvents;

/**
 * Search for events by a list of keywords.
 *
 * The search engine delegate must be set prior to the search
 * to handle any search events.
 *
 * @param keywords  a list of keywords
 * @param matchAll  YES if all keywords in the keyword list must match;
 *                  NO if any keyword can match.
 */
- (void)searchEventsByKeywords:(NSArray*)keywords 
			  matchAllKeywords:(BOOL)matchAll;

/**
 * Search for events by a spaced-delimited string of keywords.
 *
 * The search engine delegate must be set prior to the search
 * to handle any search events.
 *
 * @param keyword   a space-delimited string of keywords
 * @param matchAll  YES if all keywords in the keyword list must match;
 *                  NO if any keyword can match.
 */
- (void)searchEventsByKeywordString:(NSString*)keyword 
				   matchAllKeywords:(BOOL)matchAll;

/**
 * Search for events by a spaced-delimited string of keywords.
 *
 * The search engine delegate must be set prior to the search
 * to handle any search events.
 *
 * @param keyword      a space-delimited string of keywords
 * @param matchAll     YES if all keywords in the keyword list must match;
 *                     NO if any keyword can match.
 * @param hasLocation  whether the events must have a location
 */
- (void)searchLocEventsByKeywordString:(NSString*)keyword 
					  matchAllKeywords:(BOOL)matchAll 
						   hasLocation:(BOOL)hasLocation;

/**
 * Display information about an event.
 *
 * Creates a new view for displaying the event information and pushes
 * that view onto the navigation controller stack of the parent
 * view. Upon tapping the back button, the view is automatically 
 * popped off the top of the navigation stack.
 *
 * @param event          the event to display
 * @param navController  the navigation controller of the parent view
 */
- (void)displayEvent:(SFUEvent*)event 
	   navController:(UINavigationController*)navController;

/**
 * Display information about a list of events.
 *
 * Creates a new view for displaying the list of events and pushes
 * that view onto the navigation controller stack of the parent
 * view. Upon tapping the back button, the view is automatically 
 * popped off the top of the navigation stack.
 *
 * @param events         the list of events to display
 * @param navController  the navigation controller of the parent view
 */
- (void)displayEvents:(NSArray*)events 
		navController:(UINavigationController*)navController;
	
/**
 * Display an event search view
 *
 * @param navController  the navigation controller of the parent view
 * @param delegate       the delegate handling event search results
 */
+ (void)searchEventsWithNavController:(UINavigationController*)navController 
					   searchDelegate:(id<SFUEventSearchEngineDelegate>)delegate;

/**
 * Display the list of bookmarked events.
 *
 * Creates a new view for displaying the list of events and pushes
 * that view onto the navigation controller stack of the parent
 * view. Upon tapping the back button, the view is automatically 
 * popped off the top of the navigation stack.
 *
 * @param navController  the navigation controller of the parent view
 * @return               whether there are bookmarks to display
 */
- (BOOL)displayBookmarkedWithNavController:(UINavigationController*)navController;
	
@end